<?php
// +----------------------------------------------------------------------
// | title: 标题注释
// +----------------------------------------------------------------------
// | Author: TZ.Leong
// +----------------------------------------------------------------------
// | Date: 2019/7/19 16:11
// +----------------------------------------------------------------------

namespace app\single\model;


use Composer\Util\Platform;
use think\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\DbException;
use think\exception\PDOException;
use think\facade\Log;
use think\Model;

class PayModel extends Model
{
    public function initialize()
    {
        $this->table = null;
    }

    /**
     * 插入玩家充值元宝累计表
     * @param int $roleId 玩家区服ID
     * @param int $chargeType 充值类型1-元宝2-月卡3-基金
     * @param int $gold 充值元宝数
     * @param int $rmb 充值人民币
     * @param array $payLogArr 充值信息
     * @return array|int[]
     * @throws PDOException
     */
    public function addPay(int $roleId, int $chargeType = 1, int $gold = 0, int $rmb = 0, array $payLogArr = array()): array
    {
        //玩家必须
        if (empty($roleId)) {
            return ["ret" => STATUS_PLAYER_NOT_EXIST];
        }
        //充值类型是否合法
        $chargeTypeConf = getDiffConfig("recharge_type", getVer());
//        Log::write("chargeTypeConf" . json_encode($chargeTypeConf[$chargeType]));
        if (!isset($chargeTypeConf[$chargeType])) {
            return ["ret" => STATUS_RECHARGE_TYPE_ERROR];
        }
        //充值子类型
        $chargeSubType = $payLogArr["sub_type"];
        $tid = $chargeSubType;
//        Log::write("chargeSubType" . $chargeSubType . "payLogarr:" . json_encode($payLogArr)."chargeType=>".$chargeType.__LINE__);
        //判断充值金额合法性
        $confRmb = $chargeTypeConf[$chargeType]["rmb"] ?? 0;
//        $cf =$chargeTypeConf[$chargeType];
//        Log::write("debug cf".json_encode($cf).__LINE__);
        if ($confRmb == 0 && $rmb > 0) {
            //充值子类型是否合法
            $chargeSubTypeConf = getSubChargeConfig($chargeType, $chargeSubType, getVer());
//            Log::write("chargeSubTypeConf" . json_encode($chargeSubTypeConf));
            if (empty($chargeSubTypeConf)) {
                return ["ret" => STATUS_RECHARGE_SUBTYPE_ERROR];
            }

            if ($chargeSubTypeConf["rmb"] != $rmb) {
//                Log::write("chargeSubTypeConf rmb != rmb ====>" . $chargeSubTypeConf["rmb"] . "=====>" . $rmb);
                return ["ret" => STATUS_RECHARGE_SUBTYPE_ERROR];
            }
        }
        $itemArr = [];
        //检测赠送道具是否合法
        if (!empty($payLogArr["items"])) {
            //赠送道具配置表
            $itemsConf = getDiffConfig("recharge_customization", getVer());
            $diyType = $chargeType . "-" . $chargeSubType;
            if (!isset($itemsConf[$diyType])) {
                return ["ret" => STATUS_CUSTOM_ITEM_INVALID];
            }
            $itemsConf = $itemsConf[$diyType];
            //切割道具类型，用 | 分割, (type,sub_type|type,sub_type)
            $itemArr = explode("|", $payLogArr["items"]);
            foreach ($itemArr as $i => $item) {
                $i++;
                //按位置来校验配置的格子位置
                if (!isset($itemsConf["items"]["list" . $i]) || !in_array($item, $itemsConf["items"]["list" . $i])) {
                    return ["ret" => STATUS_CUSTOM_ITEM_INVALID];
                }
            }
        }
        $payLogModel = new PayLogModel();
        //充值类型处理
//        switch ($chargeType) {
//            case 1:
//                //普通充值元宝
//                $chargeSubType = 0;
//                break;
//            case 2:
//                //双倍充值元宝
//                $chargeSubType = $gold; //648 = 6480
//                break;
//            case 3:
//                //四倍充值，只能充值一个档位，多余的按照普通充值元宝处理
//                if ($payLogModel->checkPayType($roleId, $chargeType)) {
//                    $chargeType = 1;
//                    $chargeSubType = 0;
//                } else {
//                    $chargeSubType = $gold;
//                }
//                break;
//            case 5:
//            case 6:
//            case 7:
//            case 8:
//            case 4:
//            case 9:
//            case 10:
//            case 11:
//            case 12:
//                break;
//            default:
//                //购买道具默认数量为1
//                $gold = 1;
//                break;
//        }
        //开启主库事物提交
        $this->startTrans();
        try {
            //如果rmb > 0，代表是正式充值，需要加入充值流水
            if ($rmb > 0 && $payLogArr) {
                //这里需要写流水
                $payLogArr["gold"] = $gold;
                unset($payLogArr["id"]);


            }
            //充值数据role_pay
            $payData["role_id"] = $roleId;
            $payData["cp_order_id"] = $payLogArr["cp_order_id"] ?? "";
            $payData["class"] = $chargeType;
            $payData["type"] = $chargeSubType;
            $payData["value"] = $gold;
            $payData["rmb"] = $rmb;
            unset($payData["id"]);
//            Log::write("insert data" . json_encode($payData));
//            $this->insert($payData);
            //自定义定制直购类型，items为自选道具
            if (!empty($itemArr)) {
                $this->itemsHandle($roleId, $itemArr);
            }
            //都插入成功，提交事物
//            $this->commit(); //11:52
            //通知服务端更新
            $isMoni = false;
            $chargeRmb =0;
            if ($rmb ==0 ) { //模拟充值
                $sn = 'moni'.substr(md5(uniqid(mt_rand(), true)), 0, 16);
                $chargeSubTypeConf = getSubChargeConfig($chargeType, $chargeSubType, getVer());
                $rmb = $chargeSubTypeConf["rmb"] ;
                $isMoni = true;
//                Log::write("eConf rmb".$rmb ."CONFIG RMB" .$confRmb .__LINE__);
            }else {
                $sn = $payLogArr["cp_order_id"];
                $chargeRmb =$rmb;
            }
             $payTotalModel = new PayTotalModel();
             $total_charge = (int)($payTotalModel->getRmb($roleId) + $chargeRmb); 

            $Paydata = [
                "RoleType" => 2,#  						1-玩家名字  2-玩家id  用来说明  IdOrName 字段
                "IdOrName" => $roleId,# / 10001,				账号id或者忘记名字
                "Platform" => PLATFORM,#						平台
                "ZoneId" => PLAT_SERVER_ID, #							节点id
                "Sn" => $sn,        #			加密唯一充值编号
                "Amount" => $rmb, #							充值金额
                "CurrencyType" => "CNY", #					货币类型 CNY	货币类型
                "Category" => 1, #  						充值类型 1：普通充值、2：自充值、3：测试充值
                "package_id" => $tid,     #				充值表(charge_data表)中的id
                "charge_type" => $chargeType,#可选				充值类型
                "package_name" => "weixinh5",#可选		包名
                "pay_channel" => "wx",#可选			充值渠道
                //todo: 下个版本更新出去
                "total_charge" => $total_charge,
            ];

            //{2,1000000006,xiwan,1,,0,0,1,26,2,0,0}
//            {2,1000000006,xiwan,1,17de7580b60d071e,0,0,1,24,2,0,0}
            //{2,1000000006,xiwan,1,26d432fc399535da,0,CNY,1,27,2,weixinh5,wx}"
//            {2,1000000012,banshu,1,banshu110000214ys3ln,6,0,1,1,0,0,0}
            $newdata = [$Paydata["RoleType"], $Paydata["IdOrName"], $Paydata["Platform"], $Paydata["ZoneId"], $sn, (int)$Paydata["Amount"],
                (int)$Paydata["CurrencyType"], (int)$Paydata["Category"], (int)$Paydata["package_id"], (int)$Paydata["charge_type"],
                (int)$Paydata["package_name"], (int)$Paydata["pay_channel"],(int)$total_charge];

            $result = PHP2Erlang(BACKGROUND_RECHARGE, $newdata);
//            Log::write("debug pay  result" . json_encode($result,JSON_UNESCAPED_UNICODE));
            //todo: 下个版本需要更新出去
            // $result["code"] =  BACKGROUND_SUCCESS; //这里屏蔽掉发货的
            if ($result["code"] === BACKGROUND_SUCCESS) {
                if (!$isMoni){  //非模拟充值要写数据
                    $res = $payLogModel->addPayLog($payLogArr);
                    //更新充值总数
                   
                    $payTotalModel->setRmb($roleId, $rmb);
                }
                return ["ret" => STATUS_SUCCESS];
            } else {
                Log::write("debug error php erlang failed error code" . json_encode($result, JSON_UNESCAPED_UNICODE), "error");
                return ["ret" => STATUS_PENDING];
            }
        } catch (\Exception $e) {
            //失败回滚
            Log::write("debug error" . $e->getMessage());
            $this->rollback();
            return ["ret" => STATUS_DELIVERY_FAILED, "message" => $e->getMessage()];
        }
    }

    /**
     * 定制可选类型
     * @param $roleId
     * @param $itemArr
     * @return void
     */
    private function itemsHandle($roleId, $itemArr): void
    {
        $itemData = [];
        foreach ($itemArr as $item) {
            $vo = explode(",", $item);
            $itemData[] = [
                "role_id" => $roleId,
                "type" => $vo[0],
                "sub_type" => $vo[1],
                "value" => 1
            ];
        }
        $this->insertAll($itemData);
    }

    /**
     * 查询充值类型是否已经有记录
     * @param $roleId
     * @param $payType
     * @return bool
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function checkPayType($roleId, $payType): bool
    {
        $map["role_id"] = $roleId;
        $map["type"] = $payType;
        $info = $this->where($map)->find();
        if ($info) {
            return true;
        }
        return false;
    }

    /**
     * 检查充值验签
     * @param $data
     * @return bool
     */
    public function checkSign($data): bool
    {
        $paySign = $data['paySign'];
        unset($data['paySign']);
        $newSign = createSign($data, config("secure." . GAME_NAME . '_key.PAY'));
        if ($newSign === $paySign) {
            return true;
        }
        return false;
    }
}